<?php

/**
 * @package docBookCompiler
 * @author Vladimir Krivosheev
 * @version $Id: Parser.php 10 2006-10-22 08:22:25Z develar $
 */
class Parser_docBookCompiler
{
	/**
	 * Каталог файлов
	 * @var string
	 */
	public $dir;

	/**
	 * ID раздела документа (index-файла)
	 * @var string
	 */
	protected $id;
	/**
	 * ID текущего обрабатываемого файла
	 * @var string
	 */
	protected $currentId;

	/**
	 * Имя текущего обрабатываемого файла
	 * @var string
	 */
	protected $fileName;

	/**
	 * DOM текущего обрабатываемого файла
	 * @var object
	 */
	protected $Doc;

	protected $indexTagName;

	const XmlNamespaceUri = 'http://www.w3.org/XML/1998/namespace';
	const DIR_EXAMPLES = '_examples';
	const INDEX_FILE_NAME = 'index.xml';

	/**
	 * @param string $dir Каталог обрабатываемых файлов
	 * @param string $id ID раздела документа (index-файла)
	 */
	public function __construct($dir, $id)
	{
		$this->dir = $dir;
		$this->id = $id;
	}

	public function openIndex()
	{
		$this->Doc = new DOMDocument();
		$this->Doc->load($this->dir . DIRECTORY_SEPARATOR . self::INDEX_FILE_NAME);
		$this->indexTagName = $this->Doc->documentElement->nodeName;

		// для корневого тега выходного документа id не задаем
		if ($this->id !== '')
		{
			$this->setId();
		}
		$this->setExample();
		return iconv_substr($this->Doc->saveXML($this->Doc->documentElement), 0, -iconv_strlen("</{$this->indexTagName}>", 'UTF-8'), 'UTF-8');
	}

	public function closeIndex()
	{
		return '</' . $this->indexTagName . '>';
	}

	public function doc($file_name)
	{
		$this->fileName = $file_name;
		$this->Doc = new DOMDocument();
		$this->Doc->load($this->dir . DIRECTORY_SEPARATOR . $this->fileName);
		$this->setId();
		$this->setExample();
		return $this->Doc->saveXML($this->Doc->documentElement);
	}

	protected function setId()
	{
		$this->currentId = $this->id;
		if (!is_null($this->fileName))
		{
			if ($this->currentId != '')
			{
				$this->currentId .= '.';
			}
			$this->currentId .= DocBookCompiler::fileNameToId($this->fileName);
		}

		if ($this->getIdAttribute($this->Doc->documentElement) === '')
		{
			$this->setIdAttribute($this->Doc->documentElement);
		}
		else
		{
			$this->logicError('It is forbidden to set id to root element');
		}
	}

	/**
	 * @todo регистрация обработчиков
	 */
	protected function setExample()
	{
		$Example = new Example_Parser_DocBookCompiler($this);
	}

	public function logicError($message)
	{
		$path_name = $this->dir . DIRECTORY_SEPARATOR;
		$path_name .= (is_null($this->fileName)) ? self::INDEX_FILE_NAME : $this->fileName;
		throw new LogicException("$message: $path_name");
	}

	/**
	 * Устанавливает атрибут ID в зависимости от версии DocBook
	 */
	public function setIdAttribute(DOMElement $DomElement, $id = null)
	{
		if (is_null($id))
		{
			$id = $this->currentId;
		}
		else
		{
			$id = $this->currentId . '.' . $id;
		}

		if (DOCBOOK_VERSION > 4)
		{
			$DomElement->setAttributeNS(self::XmlNamespaceUri, 'id', $id);
		}
		else
		{
			$DomElement->setAttribute('id', $id);
		}
	}

	public function getIdAttribute(DOMElement $DomElement)
	{
		if (DOCBOOK_VERSION > 4)
		{
			return $DomElement->getAttributeNS(self::XmlNamespaceUri, 'id');
		}
		else
		{
			return $DomElement->getAttribute('id');
		}
	}
}

?>